-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[typescript] Make types of componentsProps consistent #27499
Conversation
ab81384
to
eb45be2
Compare
Should we update pickers, date picker, and autocomplete too? |
In Autocomplete we have |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the point of making the types consistent when it reduces type coverage in some cases?
Consistency is not a target. It's an indicator for other problems. So we need to make sure we understand the problem. Just because something is inconsistent, doesn't mean we need to fix it. For example, apples and bananas are inconsistent fruits. Doesn't mean we need to invent a banana-apple to have consistent fruits.
@eps1lon Take a look at the discussion in #26810 for rationale. I'm not doing this just for the sake of consistency. I believe having For DX it would be ideal if |
The general direction so far has been "strict by default" and let developers loosen up type-checking if they need to. The reverse is usually not possible. This goes against that direction since you can now write I do agree that module augmentation is the wrong tool here since it applies globally. I think we discussed inferring a while back? Can you share the latest progress so that I can poke at it a bit? |
I haven't looked into it much since we talked about it. Just added some type tests in SwitchUnstyled.spec.tsx: |
@eps1lon have you had a chance to take a look at the code in my |
We got the first issue about type errors in componentsProps: #27869 I think, at the very least, we can type It would still require casting when something else is provided to |
I like this. |
@michaldudak Sounds great, and identical to the current tradeoff of the |
@michaldudak we can go with your proposal, there has been a week without a complain, so let's push this forward :) |
Sure, it's on my to-do list. I'll likely start today. |
After further thought, I decided to use just HTMLAttributes / ComponentProps of the default component and not augment it with As for |
Originally, the If we sent directly this prop to the unstyled component, we would need to also configure somehow that it should not be spread on the DOM elements. |
We discussed it with @mnajdova off-site and came to the conclusion that adding more properties to componentsProps={{
root: {
- ...componentsProps.root,
- ...((!components.Root || !isHostComponent(components.Root)) && {
- ownerState: { ...componentsProps.root?.ownerState, color },
- }),
+ color: isHostComponent(BadgeRoot) ? undefined : color,
}, Obviously, this creates another problem with typing the componentsProps. We haven't found anything better than: export interface BadgeComponentsPropsOverrides {}
// ...
componentsProps: {
root: React.HTMLAttributes<HTMLSpanElement> & BadgeComponentsPropsOverrides;
badge: React.HTMLAttributes<HTMLSpanElement> & BadgeComponentsPropsOverrides;
} This will allow developers to use all the standard HTML attributes out of the box and add custom ones using module augmentation. |
export interface BadgeComponentsPropsOverrides {}
// ...
componentsProps: {
root: React.HTMLAttributes<HTMLSpanElement> & BadgeComponentsPropsOverrides;
badge: React.HTMLAttributes<HTMLSpanElement> & BadgeComponentsPropsOverrides;
} I like that this is strict by default, but can be augmented to accept more props 👍 |
@michaldudak one quesiton. Should we maybe use just componentsProps: {
- root: React.HTMLAttributes<HTMLSpanElement> & BadgeComponentsPropsOverrides;
- badge: React.HTMLAttributes<HTMLSpanElement> & BadgeComponentsPropsOverrides;
+ root: React.HTMLAttributes<HTMLElement> & BadgeComponentsPropsOverrides;
+ badge: React.HTMLAttributes<HTMLElement> & BadgeComponentsPropsOverrides;
} |
HTMLElement, HTMLDivElement, HTMLSpanElement and many others are actually equivalent in this context. |
@oliviertassinari, @mnajdova, @eps1lon Is there anything else you'd like to see changed, or is this good to go? I think it's worth merging it before the next RC. |
As discussed in #26810, this changes the types of unstyled components'componentsProps
fields toRecord<string, any>
.This PR sets the type of
componentsProps
' fields to the props of the matching defaultcomponents
field.It eliminates the need for module augmentation when the default (or compatible) components are used.
Closes #26810
Closes #27929
Closes #27869